import {info, clear} from './logview/index.js'
import _ from "lodash"
import api from "../request/apis.js"
// import {mapping} from "./RegisterJobTitleMapping.js";
import moment from "moment/moment.js";
// import {mapping as shiftMapping} from "./RegisterShiftMapping.js"
import {toInt} from "../utils/index.js";

export const importAppointment = async (syncMap, submitScheduleFlag,startDate) => {
    console.log("要同步的数据为", syncMap);
    clear();
    const resultMap = new Map();
    for (const bb of syncMap) {
        const value = bb[1];
        const key = bb[0];
        if (value && value.length > 0) {
            resultMap.set(key, value);
        }
    }

    const length = size(resultMap);
    info(`要同步的数据条数为${length}`);

    let index = 1;
    for (const bb of resultMap) {
        const key = bb[0];
        const value = bb[1];
        const locName = value[0].deptName;
        info(`现在开始同步科室【${locName}】配置 (${index}/${length})`);
        await deptSetting(locName, key);
        info(`科室【${locName}】同步配置结束`);

        info(`科室【${locName}】现在根据排班医生分组`);
        await locMapSync(key, locName, value);
        info(`科室【${locName}】同步完成`);

        //同步完了后现在要进行提交了
        if (submitScheduleFlag) {
            api.clearCache();
            info(`科室【${locName}】清除缓存完成`);

            info(`科室【${locName}】现在开始生成排班`);
            await submitSchedule(key, locName,startDate);
        }
        info(`科室【${locName}】生成结束 (${index}/${length})`);
        index++;


    }

}


const submitSchedule = async (locId, locName,startDate) => {
    const date = new Date(startDate);
    const validateRangeDate = getWeekBeginEnd(date);

    let scheduleList = await api.listSchedule(locId, validateRangeDate.end, validateRangeDate.start);

    if (!scheduleList || scheduleList.length <= 0) {
        return;
    }


    const ruleIds = findPlainIds(scheduleList);
    if (!ruleIds || ruleIds.length <= 0) {
        info(`科室【${locName}】没有找到需要生成排班的数据`);
        // return;
    } else {
        //去一把重
        let newRuleIds = Array.from(new Set(ruleIds));
        //现在开始提交一把了
        try {
            await api.submitSchedule(newRuleIds);
        } catch (e) {
            info(`科室【${locName}】排班生成失败, ${e}`);
            throw e;
        }
        info(`科室【${locName}】排班生成完成`);
    }

    //提交完了在查询一次
    api.clearCache();

    info(`科室【${locName}】再次清除缓存完成`);

    scheduleList = await api.listSchedule(locId, validateRangeDate.end, validateRangeDate.start);

    const scheduleRuleIds = findRuleIds(scheduleList);
    if (!scheduleRuleIds || scheduleRuleIds.length <= 0) {
        info(`科室【${locName}】没有找到需要生成号源的数据`);
    } else {
        let newScheduleRuleIds = Array.from(new Set(scheduleRuleIds));

        for (const key in newScheduleRuleIds) {
            const scheduleRuleId = newScheduleRuleIds[key];
            //提交完了就要生成号源
            try {
                await api.submitGenerate(scheduleRuleId);
                info(`科室【${locName}】 【${scheduleRuleId}】生成号源成功`);
            } catch (e) {
                info(`科室【${locName}】${scheduleRuleId} ${date}生成号源报错了 ${e}`);
            }
        }
    }

}


const findRuleIds = (scheduleList) => {
    const ruleIds = [];
    //找到所有已保存的
    for (const key in scheduleList) {
        const schedule = scheduleList[key];

        const schedulePlanVOList = schedule.schedulePlanVOList;

        if (!schedulePlanVOList || schedulePlanVOList.length <= 0) {
            continue;
        }

        for (const cKey in schedulePlanVOList) {
            const schedulePlanVO = schedulePlanVOList[cKey];
            if (schedulePlanVO.planStatus == 2 && !schedulePlanVO?.hadGeneralResource) {
                ruleIds.push(schedulePlanVO.relateRuleId);
            }
        }
    }
    return ruleIds;
}

const findPlainIds = (scheduleList) => {
    const ruleIds = [];
    //找到所有已保存的
    for (const key in scheduleList) {
        const schedule = scheduleList[key];

        const schedulePlanVOList = schedule.schedulePlanVOList;

        if (!schedulePlanVOList || schedulePlanVOList.length <= 0) {
            continue;
        }

        for (const cKey in schedulePlanVOList) {
            const schedulePlanVO = schedulePlanVOList[cKey];
            if (schedulePlanVO.planStatus == 1) {
                ruleIds.push(schedulePlanVO.id);
            }
        }
    }
    return ruleIds;
}

const size = (map) => {

    if (!map) {
        return 0;
    }

    let i = 0;

    try {
        for (const key of map) {
            i++;
        }
    } catch (e) {
        for (const key in map) {
            i++;
        }
    }

    return i;

}

const locMapSync = async (deptId, locName, doctorList) => {
    // let index = 1;
    // const length = doctorList.length;

    let docMap = _.groupBy(doctorList, (index) => {
        return index.doctorId;
    });
    await docMapSync(deptId, locName, docMap);

}


const docMapSync = async (deptId, deptName, docMap) => {
    if (!docMap) {
        info(`科室【${deptName}】没有医生排班数据，直接返回了`);
        return;
    }
    let index = 1;
    const length = size(docMap);
    for (const key in docMap) {
        let dataArray = docMap[key];
        const doctorName = dataArray[0]?.doctorName;
        info(`科室【${deptName}】医生【${doctorName}】开始同步 (${index}/${length})`);

        //这里需要进行合并
        dataArray = docMerge(dataArray);
        api.clearCache();
        for (const e in dataArray) {
            await docSync(deptId, deptName, key, doctorName, dataArray[e]);
        }
        info(`科室【${deptName}】医生【${doctorName}】同步结束 (${index}/${length})`);
        index++;
    }

}


const docSync = async (deptId, deptName, docId, docName, data) => {


    //现在开始新增排班
    await saveScheduleConfig(data);

}


const saveScheduleConfig = async (data) => {
    const serviceDateStr = data.serviceDate;
    if (!serviceDateStr) {
        info(`科室【${data.deptName}】医生【${data.doctorName}】同步失败，找不到服务日期直接返回了`);
        throw "同步失败";
    }

    const week = weekCheck(new Date(`${serviceDateStr} 00:00:00`));
    if (!week) {
        info(`科室【${data.deptName}】医生【${data.doctorName}】【${serviceDateStr}】同步失败，获取星期失败`);
        throw "同步失败";
    }

    const validateRangeDate = getWeekBeginEnd(new Date(`${serviceDateStr} 00:00:00`));
    //判断是否已经同步过了
    const hasSaveFlag = await hasSave(validateRangeDate, data);
    if (hasSaveFlag) {
        info(`科室【${data.deptName}】医生【${data.doctorName}】星期【${week}】班次【${data.shiftName}】同步失败，已经有数据了`);
        return;
    }

    const shiftMpInfo = await shiftSeassonInfo(data.shiftId);
    if (!shiftMpInfo) {
        info(`科室【${data.deptName}】医生【${data.doctorName}】星期【${week}】班次【${data.shiftName}】同步失败，获取班次映射信息失败`);
        throw "同步失败";
    }
    if (!shiftMpInfo.shiftId) {
        info(`科室【${data.deptName}】医生【${data.doctorName}】星期【${week}】班次【${data.shiftName}】同步失败，获取班次映射信息新系统班次ID失败`);
        throw "同步失败";
    }
    if (!shiftMpInfo.shiftSeasonId) {
        info(`科室【${data.deptName}】医生【${data.doctorName}】星期【${week}】班次【${data.shiftName}】同步失败，获取班次映射信息新系统shiftSeasonId失败`);
        throw "同步失败";
    }


    const saveJson = {
        "deptId": data.deptId,//科室
        "providerId": data.doctorId,//医生
        "locationId": data.locationId,//地址-诊区
        "serviceItemCategory": data.registerCategoryCode,//挂号类别
        "serviceItemId": data.registerLevelId,//挂号级别
        "numExtraLimit": 999,//加号限额
        "numLimit": parseInt(data.load),//号源数
        "frequencyValues": [//星期几
            week], "shiftId": shiftMpInfo.shiftId,//班次ID
        "validDate": validateRangeDate.start,//一周开始时间
        "expireDate": validateRangeDate.end,//一周结束时间
        "shiftSeasonList": [//班次时令
            {
                "beginTime": getHours(data.beginTime),//开始时间
                "endTime": getHours(data.endTime),//结束时间
                "shiftSeasonId": shiftMpInfo.shiftSeasonId//排次时令id
            }]
    };
    // console.log(saveJson)
    await api.saveSchedule(saveJson);
}

const getHours = (dateTime) => {
    const date = moment(new Date()).format('YYYY-MM-DD');
    const dateStr = date + " " + dateTime;
    return moment(new Date(dateStr)).format('HH:mm');
}

const hasSave = async (validateRangeDate, data) => {
    const scheduleList = await api.listSchedule(data.deptId, validateRangeDate.end, validateRangeDate.start);

    if (!scheduleList) {
        return false;
    }

    let shiftMpInfo = await shiftSeassonInfo(data.shiftId);
    if (!shiftMpInfo) {
        shiftMpInfo = {}
    }
    const week = weekCheck(new Date(`${data.serviceDate} 00:00:00`));
    let result = false;
    for (const key in scheduleList) {
        const schedule = scheduleList[key];

        const schedulePlanVOList = schedule.schedulePlanVOList;
        if (!schedulePlanVOList || schedulePlanVOList.length <= 0) {
            continue
        }
        //班次匹配上了
        if (schedule.shiftId == shiftMpInfo.shiftId && schedule.providerId == data.doctorId) {
            //还要匹配星期
            for (const cKey in schedulePlanVOList) {
                const schedulePlanVO = schedulePlanVOList[cKey];

                if (schedulePlanVO.shiftId == shiftMpInfo.shiftId && schedulePlanVO.frequencyValue == week + "" && schedulePlanVO.providerId == data.doctorId) {
                    result = true;
                    break;
                }
            }
        }
    }
    return result;
}


const shiftSeassonInfo = async (shiftId) => {
    // shiftMpInfo.shiftId;
    const shiftList = await api.getShiftList();
    if (!shiftList) {
        return;
    }
    let result = null;
    for (const key in shiftList) {
        const shift = shiftList[key];
        if (shift.shiftId == shiftId) {
            result = shift;
            break;
        }
    }
    if (!result) {
        return null;
    }

    return {
        shiftId: result.shiftId, shiftSeasonId: result.shiftSeasons[0]?.shiftSeasonId
    }
}

const docMerge = (dataArray) => {
    let result = [];
    //现在开始合并，如果日期+班次+医生一致则要进行合并
    for (const e in dataArray) {
        const data = dataArray[e];
        const matchData = hasMatchDocMergeCondition(result, data);
        if (matchData) {
            info(`科室【${matchData.deptName}】医生【${matchData.doctorName}】发生了合并`);
            matchData.load = toInt(matchData.load || 0) + toInt(data.load || 0);
        } else {
            result.push(data);
        }
    }

    return result;
}


const hasMatchDocMergeCondition = (result, data) => {
    if (!result || result.length <= 0) {
        return null;
    }
    //如果日期+班次+医生一致则要进行合并
    let matchObj = null;
    for (let resultKey in result) {
        const resultObj = result[resultKey];

        if (resultObj.doctorId == data.doctorId && data.shiftId == resultObj.shiftId && data.serviceDate == resultObj.serviceDate) {
            matchObj = resultObj;
            break;
        }
    }
    return matchObj;
}

const deptSetting = async (deptName, locId) => {
    if (!locId) {
        return;
    }

    info(`科室【${deptName}】同步配置，获取配置信息`);
    //先查询
    const deptConfig = await api.getScheduleDeptConfigDetail(locId);

    if (!deptConfig) {
        info(`科室【${deptName}】同步配置，没有获取到配置信息，走新增配置`);
        await addDeptConfig(locId, 5);
        info(`科室【${deptName}】同步配置，没有获取到配置信息，新增配置结束`);
    } else {
        //不管
        info(`科室【${deptName}】同步配置，获取到了配置信息，所以不处理`);
    }
}


const addDeptConfig = async (locId, trLength) => {
    //需要计算时段长度
    const saveJson = {
        "deptId": locId,//科室名称
        "overtimeExpire": 0,//过时限制 是否可以过时取号
        "scheduleInterval": trLength || 30,//时段长度
        "registrationExpirationDays": 3,//复诊有效时间 todo 需要确认下
        "gender": "",//性别限制 不限
        "ageMinLimit": 0,//年龄限制
        "ageMaxLimit": 100,//年龄限制
        "ageUnit": "YEAR",//年龄限制
        "campusId": "30001002",//院区
        "orgId": "20001001"//机构
    }
    //保存
    await api.saveDeptConfig(saveJson);
}

const getWeekBeginEnd = (date) => {
    var s = weekCheck(date);

    const start = moment(date).subtract(s - 1, 'days').format('YYYY-MM-DD');
    const end = moment(date).add(7 - s, 'days').format('YYYY-MM-DD');
    return {
        start, end
    };
}

const weekCheck = (date) => {
    let s = moment(date).format("E");
    return s;
}